package org.cos.generation.epda;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.cos.generation.epda.action.Action;

/**
 * Represent an EPDA. 
 * @author ZXD
 *
 */

public class EPDA implements EPDAGetter, EPDASetter {
	
	/** Store the states of EPDA. */
	private List<State> states;
	
	/** Store the active state index. */
	private int activeStateIndex;
	
	/**
	 * Constructor.
	 */
	public EPDA() {
		states = new ArrayList<State>();
		activeStateIndex = newState();
	}
	
	/**
	 * Get the active state index.
	 * @return
	 */
	public int getActiveStateIndex() {
		return activeStateIndex;
	}
	
	/**
	 * Get the active state.
	 * @return
	 */
	public State getActiveState() {
		return states.get(activeStateIndex);
	}
	
	/**
	 * Get the all states.
	 * @return
	 */
	public List<State> getStates() {
		return states;
	}
	
	/**
	 * Get the number of the states.
	 * @return
	 */
	public int getStateSize() {
		return states.size();
	}
	
	/**
	 * Create a new state.
	 * @return
	 */
	public int newState() {
		states.add(new State(states.size()));
		return states.size() - 1;
	}
	
	/**
	 * Add a new transition form active state to a new state. 
	 * @param method
	 * @param conditions
	 * @param actions
	 */
	public void grow(Method method,	List<Condition> conditions, 
			LinkedList<Action> actions) {
		State activeState = getActiveState();
		int newStateIndex = newState();
		activeState.addTransition(newStateIndex, method, conditions, actions);
		trans(newStateIndex);
	}
	
	/**
	 * Add a new transition form active state to a given state.
	 * @param tailIndex
	 * @param method
	 * @param conditions
	 * @param actions
	 */
	public void link(int tailIndex, Method method,	
			List<Condition> conditions,	List<Action> actions) {
		getActiveState().addTransition(tailIndex, method, conditions, actions);
	}
	
	/**
	 * Transform to a given state.
	 * @param stateIndex
	 */
	public void trans(int stateIndex) {
		activeStateIndex = stateIndex;
	}
	
	/**
	 * Delete all states.
	 */
	public void clear() {
		states.clear();		
	}
	
	/**
	 * Add a list of states.
	 * @param size
	 * @param states
	 */
	public void addStates(int size, State states[]) {
		for (int i = 0; i < size; i++) {
			this.states.add(states[i]);
		}
	}

}
